/*
S.Shanmugaesan (1061630)  Michael Antemann (1061753)
Computergrafik II
30.04.09
*/
#include <GL/gl.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define x01 -100
#define y01  0

#define x04 100
#define y04 0

#define x1a2 0
#define y1a2 60

#define x4a3 40
#define y4a3 160

#define genauigkeit 0.000000001
#define iterationsAnzahl 100


// Koordinaten für den Körper2:
double x_koerper1 = -100;
double y_koerper1 = 60;

double x_koerper3 = 140;
double y_koerper3 = 160;

//Winkel
int theta1_deg = 0;		//eingabewinkel als DEg
double theta1_rad;	//der Eingabewinkel (als Rad)
double theta4_rad;	//Der Errechnete Winkel

//UMwandeln von degres in rad
double DegToRad(int d);
double RadToDeg(double r);


//transzendenten Gleichung für theta4
double gleichung(double theta1_rad, double theta4_rad)
{
	return(sqrt(pow((-y1a2*cos(theta1_rad) + 
				y4a3*cos(theta4_rad) + 
				x4a3*sin(theta4_rad)),2) + 
				pow((-x01 + x04 + x4a3*cos(theta4_rad) + 
				y1a2*sin(theta1_rad) - y4a3*sin(theta4_rad)),2))-260);
}

//Berechnung der Nullstelle theta4
void iterationTheta4()
{
	double theta4_alt = theta4_rad - 0.001;
	double theta4_neu = theta4_rad;
	double theta4_tmp = 0;
	int counter = 0;
  /* Sekantenverfahren*/
	do
	{
		theta4_tmp = theta4_neu - ((theta4_neu - theta4_alt) / 
					(gleichung(theta1_rad, theta4_neu) - gleichung(theta1_rad, theta4_alt))) * gleichung(theta1_rad, theta4_neu);
		
		//alten wert fuer die nächste Berechnung speichern
		theta4_alt = theta4_neu;
		
		//neuen Wert in den theta4_neu speichern
		theta4_neu = theta4_tmp;
		printf("Theta4 im Loop: %lf\n", theta4_neu);
		counter++;
	}while(((fabs(theta4_alt - theta4_neu )) > genauigkeit) && 
			counter < iterationsAnzahl && 
			(fabs(gleichung(theta1_rad, theta4_neu)) > genauigkeit) );

	//Genauigkeit erreicht und jetzt nach aussen schreiben
	theta4_rad = theta4_neu;
 }	

// Funktion zur Berechnung der passenden Koordinaten für den Körper2:
double berechneKoordinatenFuerKoerper2()
{
      // Berechnung der Koordinaten für den Körper 2:
	     x_koerper1 = 0.0 * cos(theta1_rad) - 60.0 * sin(theta1_rad) - 100.0; 
	     y_koerper1 = 60.0 * cos(theta1_rad) + 0.0 * sin(theta1_rad);
	     x_koerper3 = 40.0 * cos(theta4_rad) - 160.0 * sin(theta4_rad) + 100.0; 
	     y_koerper3 = 160.0 *cos(theta4_rad) + 40.0 * sin(theta4_rad); 
}
void init(void)
{
  glClearColor (0.0, 0.0, 0.0, 0.0);
  glShadeModel (GL_FLAT);
}

void display(void)
{
   glClear (GL_COLOR_BUFFER_BIT);

	 glPushMatrix();
	 glLineWidth(2.0);
	 glColor3f(1.0, 1.0, 1.0);
	 glBegin(GL_LINES);
		  glVertex2f(-180.0, 0.0);
		  glVertex2f(180.0, 0.0);
	  glEnd();
	 //glutWireCube(350);
	  //koerper 1
	  glColor3f(0.0, 0.5, 1.0);
	  glTranslatef(-100, 0.0, 0.0);
	 
	  glRotatef(RadToDeg(theta1_rad), 0.0, 0.0, 1.0);	
	  glBegin(GL_LINES);
		  glVertex2f(0.0, 0.0);
		  glVertex2f(0.0, 60);
	  glEnd();
		glPopMatrix();
	printf("Theta4 Ergebnis: %lf\n", RadToDeg(theta4_rad));
	  //koerper 2     
	  /*  Koordinatensystem wird zurückgestellt. 0,0,0  ist wieder in der Mitte   */
	 glPushMatrix();
	  glColor3f(0.0, 1.0, 0.5);
	  glBegin(GL_LINES);
		   glVertex2f(x_koerper1, y_koerper1); //-100 ,60		   
		   glVertex2f(x_koerper3, y_koerper3); //  140, 160
			printf("x_koerper1: %lf \ny_koerper1: %lf\n", x_koerper1, y_koerper1);
			printf("x_koerper3: %lf \ny_koerper3: %lf\n\n", x_koerper3, y_koerper3);
			fflush(stdout);
	  glEnd();
	  glPopMatrix();
	  //koerper 3
	  glPushMatrix();
	  glColor3f(1.0, 0.5, 0.0);
	  glTranslatef(100, 0.0, 0.0);
	  glRotatef(RadToDeg(theta4_rad), 0.0, 0.0, 1.0);
	  glBegin(GL_LINES);
		   glVertex2f(0.0, 0.0);
		   glVertex2f(40.0, 160.0);
	  glEnd();

	glPopMatrix();
	glutSwapBuffers();
      glFlush();
}

void specialKey(int key, int x, int y)
{
    switch (key) {
	case GLUT_KEY_RIGHT:	
		theta1_deg = (theta1_deg - 5) % 360;
        break;
	case GLUT_KEY_LEFT:
		//Modulo nur damit man keine winkel < 360 bekommen kann
		theta1_deg = (theta1_deg + 5) % 360;
        break;
     }
	//Nun Theta1 ausrechnen
	theta1_rad = DegToRad(theta1_deg);
	//jetzt Tehta45 ausrechnen lassen
	iterationTheta4();
	//Für den zweiten Korper ausrechen
     	berechneKoordinatenFuerKoerper2();
     	//Neu zeichnen lassen
     	glutPostRedisplay();
     	                                
}
void reshape (int w, int h)
{
   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   //gluPerspective(45.0f,(GLfloat)w/(GLfloat)h,-5,5);
   glOrtho(-200.0,200.0,-200.0,200.0,-200.0,200.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}
	
int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
   glutInitWindowSize (600, 600); 
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
   init ();
   glutDisplayFunc(display); 
      glutReshapeFunc(reshape);
   glutSpecialFunc(specialKey);
   iterationTheta4();
   glutMainLoop();
   return 0;
}

double DegToRad(int deg)
{
	//printf("Deg: %d zu Rad: %lf\n", deg, (deg * 0.017453293));
	return (deg * 0.017453293);
}

//umwandeln von rad zu grad
double RadToDeg(double rad)
{
	double deg = 0;
	deg = 180.0 / M_PI * rad;
	return deg;
}
